/*
* Copyright 2009 NOR_/D Labs <http://labs.nortd.com>
*
* This file is part of SceneExpression.
* SceneExpression is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License 
* as published by the Free Software Foundation, either version 3 of 
* the License, or (at your option) any later version. For details
* see <http://www.gnu.org/licenses/>.
*
* * *
* 
*/


#include <sx/TextShape.h>
#include <osg/BoundsChecking>

using namespace sx;

  
TextShape::TextShape() {        
    
    // text
    _text = new  osgText::Text;
    _geode->addDrawable( _text.get() );
    _defaultTypeface = "TitilliumText400wt.ttf";
    _text->setAlignment(osgText::Text::LEFT_TOP);
    _text->setFontResolution(16,16);
    _characterSize = 16.0f;
     _text->setCharacterSize(_characterSize);
     _paddingLeft = _paddingRight = _paddingTop = _paddingBottom = 0.0f;

    setPosition(0.0f, 0.0f, 0.0f);
    setShape(100, 25);
    setBackgroundColor(0.0f, 0.0f, 0.0f, 0.3f);
    
    //state
    disableLighting();
    disableDepthTest();
    enableBlending();    
}

void TextShape::setText( std::string text ) {
    _text->setText(text);
}
std::string TextShape::getText() {
    return _text->getText().createUTF8EncodedString();
}

void TextShape::setCharacterSize( float size ) {
    // many successive calls seem to lead to crashes
    _text->setCharacterSize(size);
}
float TextShape::getCharacterSize() {
    return _text->getCharacterHeight();
}
        
void TextShape::setColor( float r, float g, float b, float a ) {
    _text->setColor(osg::Vec4(r,g,b,a));
}

void TextShape::setBackgroundColor( osg::Vec4 color ) {
    _colors->clear();
    _colors->push_back(color);
    _geometry->dirtyDisplayList();
}
void TextShape::setBackgroundColor( float r, float g, float b, float a ) {
    setBackgroundColor(osg::Vec4(r,g,b,a));
}
osg::Vec4 TextShape::getBackgroundColor() {
    return *(_colors->begin());
}

void TextShape::setPadding( float padding ) {
    _paddingLeft = _paddingRight = _paddingTop = _paddingBottom = padding;
    reshape();
}

void TextShape::setLayout( Layout layout ) {
        _text->setLayout(osgText::Text::Layout(layout));
}


void TextShape::setShape( float width, float height) {
    _width = width;    
    _height = height;
    reshape();    
}   
float TextShape::getWidth() {
    return _width;
}   
float TextShape::getHeight() {
    return _height;
}  

void TextShape::reshape() {
    // define geometry
    _vertices->clear();
    addRoundedRect(0.0f, 0.0f, _width, _height, 6.0f, _vertices.get());
    _drawArray->setCount(_vertices->size());
    //_borderDrawArray->setCount(_backgroundVertices->size());
    
    //text
    //setColor(1.0f, 1.0f, 1.0f, 1.0f);
    _text->setFont(_defaultTypeface);
    _text->setPosition(osg::Vec3(_paddingLeft, _height - _paddingTop, 0.0f));
    _text->setMaximumWidth(_width - _paddingLeft - _paddingRight);
    _text->setMaximumHeight(_height - _paddingTop - _paddingBottom+getCharacterSize());
}


// Misc
//
void TextShape::addRoundedRect( float x, float y, float w, float h, float r, osg::Vec3Array* vertices ) {
    vertices->push_back(osg::Vec3( x+r, y, 0.0f));
    vertices->push_back(osg::Vec3( x+w-r, y, 0.0f));
    roundedCorner( x+w-r, y, x+w-r, y+r, vertices );
    vertices->push_back(osg::Vec3( x+w, y+r, 0.0f));
    vertices->push_back(osg::Vec3( x+w, y+h-r, 0.0f));
    roundedCorner( x+w, y+h-r, x+w-r, y+h-r, vertices );
    vertices->push_back(osg::Vec3( x+w-r, y+h, 0.0f));
    vertices->push_back(osg::Vec3( x+r, y+h, 0.0f));
    roundedCorner( x+r, y+h, x+r, y+h-r, vertices );
    vertices->push_back(osg::Vec3( x, y+h-r, 0.0f));
    vertices->push_back(osg::Vec3( x, y+r, 0.0f));
    roundedCorner( x, y+r, x+r, y+r, vertices );
    vertices->push_back(osg::Vec3( x+r, y, 0.0f));
}
void TextShape::roundedCorner( float x, float y, float pivotX, float pivotY, osg::Vec3Array* vertices ) {
    float a = osg::PI*0.125;  //0.5*PI is 90deg
    vertices->push_back(osg::Vec3( ((x-pivotX)*cos(a) - (y-pivotY)*sin(a)) + pivotX, 
                                   ((x-pivotX)*sin(a) + (y-pivotY)*cos(a)) + pivotY,
                                   0.0f  ));
    a = osg::PI*0.1875;
    vertices->push_back(osg::Vec3( ((x-pivotX)*cos(a) - (y-pivotY)*sin(a)) + pivotX, 
                                   ((x-pivotX)*sin(a) + (y-pivotY)*cos(a)) + pivotY,
                                   0.0f  ));
    a = osg::PI*0.25;
    vertices->push_back(osg::Vec3( ((x-pivotX)*cos(a) - (y-pivotY)*sin(a)) + pivotX, 
                                   ((x-pivotX)*sin(a) + (y-pivotY)*cos(a)) + pivotY,
                                   0.0f  ));
    a = osg::PI*0.3125;
    vertices->push_back(osg::Vec3( ((x-pivotX)*cos(a) - (y-pivotY)*sin(a)) + pivotX, 
                                   ((x-pivotX)*sin(a) + (y-pivotY)*cos(a)) + pivotY,
                                   0.0f  ));
    a = osg::PI*0.375;
    vertices->push_back(osg::Vec3( ((x-pivotX)*cos(a) - (y-pivotY)*sin(a)) + pivotX, 
                                   ((x-pivotX)*sin(a) + (y-pivotY)*cos(a)) + pivotY,
                                   0.0f  ));
    a = osg::PI*0.4375;
    vertices->push_back(osg::Vec3( ((x-pivotX)*cos(a) - (y-pivotY)*sin(a)) + pivotX, 
                                   ((x-pivotX)*sin(a) + (y-pivotY)*cos(a)) + pivotY,
                                   0.0f  ));
}
